﻿#pragma once
#include "Common.h"

template <class T> 
class MemoryPool
{
public:
	T* New()
	{
		// 如果自由链表有空闲空间，先去自由链表
		T* tmp = nullptr;
		if (_freeList)
		{
			//tmp = (T*)_freeList;
			tmp = reinterpret_cast<T*>(_freeList);
			_freeList = *(void**)_freeList;
		}
		// 去大块内存中去切空间
		else
		{
			// 大块内存不够开一次空间，重新分配
			if (_remainSize < sizeof(T))
			{
				_remainSize = 128 * 1024;
				_memory = (char*)SystemAlloc(_remainSize >> 13);
				// 开辟失败，异常
				if (_memory == nullptr)
					throw std::bad_alloc();
			}

			tmp = (T*)_memory;
			_remainSize -= sizeof(T);
			_memory += sizeof(T);
		}
		
		new(tmp)T;
		return tmp;
	}
	void Delete(T* tmp)
	{
		// 如果是自定义类型，需要显示调用析构函数进行释放开辟的空间
		tmp->~T();

		// 头插到自由链表
		*(void**)tmp = _freeList;
		_freeList = tmp;
	}
private:
	char* _memory = nullptr; // 大块内存空间
	int _remainSize = 0;     // 剩余空间大小
	void* _freeList = nullptr;// 用完返回的内存空间的自由链表
};
